package com.managedBean.merchant;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

import org.primefaces.event.RowEditEvent;
import org.primefaces.event.SelectEvent;

import com.controller.merchant.OrganizeMenuController;
import com.controller.merchant.ProductController;
import com.dto.merchant.Level1DTO;
import com.dto.merchant.Level2DTO;
import com.dto.merchant.Level3DTO;
import com.dto.merchant.MasterCatalogDTO;
import com.dto.merchant.MasterCatalogDataModel;

@ManagedBean(name = "productManagedBean")
@ViewScoped
public class ProductManagedBean implements Serializable {

	private static final long serialVersionUID = 1L;
	private List<MasterCatalogDTO> masterlist;
	private MasterCatalogDataModel masterCatalogDataModel;
	@ManagedProperty(value = "#{productController}")
	private ProductController productController;
	@ManagedProperty(value = "#{organizeMenuController}")
	private OrganizeMenuController organizeMenuController;
	private MasterCatalogDTO selectedMasterCatalogDTO;
	private boolean addFlag;
	private boolean editFlag;
	private String name;
	private String brand;
	private String description;
	private int l1Id;
	private int l2Id;
	private int l3Id; 
	private MasterCatalogDTO masterCatalogDTO;
	private List<Level1DTO> l1List;
	private List<Level2DTO> l2List;
	private List<Level3DTO> l3List;
	private Map<Integer,String> l1Map;
	private Map<Integer,String> l2Map;
	private Map<Integer,String> l3Map;
	
	@PostConstruct
	public void init() {
		masterlist = new ArrayList<MasterCatalogDTO>();
		masterlist = productController.findAllMasters();
		masterCatalogDataModel=new MasterCatalogDataModel(masterlist);
		l1List = new ArrayList<Level1DTO>();
		l1Map=new LinkedHashMap<Integer, String>();
		l2Map=new  LinkedHashMap<Integer, String>();
		l3Map=new LinkedHashMap<Integer, String>();
		try {
			l1List = organizeMenuController.findAll();
			for(Level1DTO level1dto:l1List){
				l1Map.put(level1dto.getL1Id(), level1dto.getL1Name());
				for(Level2DTO level2dto:level1dto.getLevel2Tables()){
					l2Map.put(level2dto.getL2Id(), level2dto.getL2Name());
					for(Level3DTO level3dto:level2dto.getLevel3Tables()){
						l3Map.put(level3dto.getL3Id(), level3dto.getL3Name());
					}
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//get the level id names
		for(MasterCatalogDTO dto:masterlist){
			dto.setL1Name(l1Map.get(dto.getL1Id()));
			dto.setL2Name(l2Map.get(dto.getL2Id()));
			dto.setL3Name(l3Map.get(dto.getL3Id()));
		}
	}

	public void onEdit(RowEditEvent event) {
		// TODO update log table
		FacesMessage msg = new FacesMessage("Product Edited",
				((MasterCatalogDTO) event.getObject()).getItemBrand() + " "
						+ ((MasterCatalogDTO) event.getObject()).getItemId());
		FacesContext.getCurrentInstance().addMessage(null, msg);
		// productController.saveOrUpdate((MasterCatalogDTO) event.getObject());
	}

	public void onCancel(RowEditEvent event) {
        FacesMessage msg = new FacesMessage("Product Cancelled");

        FacesContext.getCurrentInstance().addMessage(null, msg);
    }
	public void onSelect(SelectEvent event) {
		FacesMessage msg = new FacesMessage("Product Selected",
				((MasterCatalogDTO) event.getObject()).getItemName());
		FacesContext.getCurrentInstance().addMessage(null, msg);
		masterCatalogDTO=(MasterCatalogDTO) event.getObject();
		
	}
	
	public void l1Changed(){
		System.out.println("l1 changed");
		FacesContext fc = FacesContext.getCurrentInstance();
		String rowId=fc.getExternalContext().getRequestParameterMap().get("rowId");
		System.out.println(rowId);
	}
	public void l1Selected(){
		for(Level1DTO level1dto:l1List){
			if(level1dto.getL1Id()==l1Id){
				l2List=level1dto.getLevel2Tables();
			}
		}
	}
	
	public void l2Selected(){
		for(Level2DTO level2dto:l2List){
			if(level2dto.getL2Id()==l2Id){
				l3List=level2dto.getLevel3Tables();
			}
		}
	}
	public void add() {
		addFlag = true;
		editFlag=true;
		//TODO check edit flag
		setName(null);
		setBrand(null);
		setDescription(null);
		setL1Id(0);
		setL2Id(0);
		setL3Id(0);
	}

	public void edit() {
		addFlag = false;
		editFlag=true;
		setName(masterCatalogDTO.getItemName());
		setBrand(masterCatalogDTO.getItemBrand());
		setDescription(masterCatalogDTO.getItemDescription());
		setL1Id(masterCatalogDTO.getL1Id());
		setL2Id(masterCatalogDTO.getL2Id());
		setL3Id(masterCatalogDTO.getL3Id());
		l1Selected();
		l2Selected();
	}

	public void save() {
		MasterCatalogDTO dto = new MasterCatalogDTO();
		dto.setItemName(name);
		dto.setItemBrand(brand);
		dto.setItemDescription(description);
		dto.setL1Id(l1Id);
		dto.setL2Id(l2Id);
		dto.setL3Id(l3Id);
		try {
			if (addFlag)
				productController.addProduct(dto);
			else if (editFlag){
				dto.setItemId(masterCatalogDTO.getItemId());
				productController.saveOrUpdate(dto);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		init();
		// TODO implement exception handling
		addFlag = false;
		editFlag = false;
		FacesMessage msg = new FacesMessage("Product Added");
		FacesContext.getCurrentInstance().addMessage(null, msg);
	}
	
	public void cancel() {
		addFlag=false;
		editFlag=false;
	}

	/**
	 * @return the masterlist
	 */
	public List<MasterCatalogDTO> getMasterlist() {
		return masterlist;
	}

	/**
	 * @param masterlist
	 *            the masterlist to set
	 */
	public void setMasterlist(List<MasterCatalogDTO> masterlist) {
		this.masterlist = masterlist;
	}

	/**
	 * @return the productController
	 */
	public ProductController getProductController() {
		return productController;
	}

	/**
	 * @param productController
	 *            the productController to set
	 */
	public void setProductController(ProductController productController) {
		this.productController = productController;
	}

	/**
	 * @return the selectedMasterCatalogDTO
	 */
	public MasterCatalogDTO getSelectedMasterCatalogDTO() {
		return selectedMasterCatalogDTO;
	}

	/**
	 * @param selectedMasterCatalogDTO
	 *            the selectedMasterCatalogDTO to set
	 */
	public void setSelectedMasterCatalogDTO(
			MasterCatalogDTO selectedMasterCatalogDTO) {
		this.selectedMasterCatalogDTO = selectedMasterCatalogDTO;
	}

	/**
	 * @return the addFlag
	 */
	public boolean isAddFlag() {
		return addFlag;
	}

	/**
	 * @param addFlag
	 *            the addFlag to set
	 */
	public void setAddFlag(boolean addFlag) {
		this.addFlag = addFlag;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name
	 *            the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the brand
	 */
	public String getBrand() {
		return brand;
	}

	/**
	 * @param brand
	 *            the brand to set
	 */
	public void setBrand(String brand) {
		this.brand = brand;
	}

	/**
	 * @return the description
	 */
	public String getDescription() {
		return description;
	}

	/**
	 * @param description
	 *            the description to set
	 */
	public void setDescription(String description) {
		this.description = description;
	}

	/**
	 * @return the editFlag
	 */
	public boolean isEditFlag() {
		return editFlag;
	}

	/**
	 * @param editFlag
	 *            the editFlag to set
	 */
	public void setEditFlag(boolean editFlag) {
		this.editFlag = editFlag;
	}

	/**
	 * @return the masterCatalogDataModel
	 */
	public MasterCatalogDataModel getMasterCatalogDataModel() {
		return masterCatalogDataModel;
	}

	/**
	 * @param masterCatalogDataModel the masterCatalogDataModel to set
	 */
	public void setMasterCatalogDataModel(
			MasterCatalogDataModel masterCatalogDataModel) {
		this.masterCatalogDataModel = masterCatalogDataModel;
	}

	/**
	 * @return the l1Id
	 */
	public int getL1Id() {
		return l1Id;
	}

	/**
	 * @param l1Id the l1Id to set
	 */
	public void setL1Id(int l1Id) {
		this.l1Id = l1Id;
	}

	/**
	 * @return the l2Id
	 */
	public int getL2Id() {
		return l2Id;
	}

	/**
	 * @param l2Id the l2Id to set
	 */
	public void setL2Id(int l2Id) {
		this.l2Id = l2Id;
	}

	/**
	 * @return the l3Id
	 */
	public int getL3Id() {
		return l3Id;
	}

	/**
	 * @param l3Id the l3Id to set
	 */
	public void setL3Id(int l3Id) {
		this.l3Id = l3Id;
	}

	/**
	 * @return the masterCatalogDTO
	 */
	public MasterCatalogDTO getMasterCatalogDTO() {
		return masterCatalogDTO;
	}

	/**
	 * @param masterCatalogDTO the masterCatalogDTO to set
	 */
	public void setMasterCatalogDTO(MasterCatalogDTO masterCatalogDTO) {
		this.masterCatalogDTO = masterCatalogDTO;
	}

	/**
	 * @return the serialversionuid
	 */
	public static long getSerialversionuid() {
		return serialVersionUID;
	}

	/**
	 * @return the organizeMenuController
	 */
	public OrganizeMenuController getOrganizeMenuController() {
		return organizeMenuController;
	}

	/**
	 * @param organizeMenuController the organizeMenuController to set
	 */
	public void setOrganizeMenuController(
			OrganizeMenuController organizeMenuController) {
		this.organizeMenuController = organizeMenuController;
	}

	/**
	 * @return the l1List
	 */
	public List<Level1DTO> getL1List() {
		return l1List;
	}

	/**
	 * @param l1List the l1List to set
	 */
	public void setL1List(List<Level1DTO> l1List) {
		this.l1List = l1List;
	}

	/**
	 * @return the l2List
	 */
	public List<Level2DTO> getL2List() {
		return l2List;
	}

	/**
	 * @param l2List the l2List to set
	 */
	public void setL2List(List<Level2DTO> l2List) {
		this.l2List = l2List;
	}

	/**
	 * @return the l3List
	 */
	public List<Level3DTO> getL3List() {
		return l3List;
	}

	/**
	 * @param l3List the l3List to set
	 */
	public void setL3List(List<Level3DTO> l3List) {
		this.l3List = l3List;
	}

	/**
	 * @return the l1Map
	 */
	public Map<Integer, String> getL1Map() {
		return l1Map;
	}

	/**
	 * @param l1Map the l1Map to set
	 */
	public void setL1Map(Map<Integer, String> l1Map) {
		this.l1Map = l1Map;
	}

	/**
	 * @return the l2Map
	 */
	public Map<Integer, String> getL2Map() {
		return l2Map;
	}

	/**
	 * @param l2Map the l2Map to set
	 */
	public void setL2Map(Map<Integer, String> l2Map) {
		this.l2Map = l2Map;
	}

	/**
	 * @return the l3Map
	 */
	public Map<Integer, String> getL3Map() {
		return l3Map;
	}

	/**
	 * @param l3Map the l3Map to set
	 */
	public void setL3Map(Map<Integer, String> l3Map) {
		this.l3Map = l3Map;
	}

}
